<template>
	<view class="com-counsult-rtc" v-if="rtcShow" :style="rtcStyle">

		<view class="rtc-bg" @click="clickCtrTips">
			<!-- 大窗口 -->
			<div ref="videoBig" class="video-big" @click.stop="clickChangeFull(true)"></div>
			<!-- 小窗口 -->
			<div ref="videoSmall" class="video-small"></div>
			<!-- 缩放 -->
			<view class="rtc-zoom" v-if="isFull" @click.stop="clickChangeFull(false)">
				<text class="yyfont yy-suoxiao"></text>
			</view>
			<!-- tips -->
			<view class="rtc-tips-box" v-if="rtcTips">
				<view class="rtc-tips">通话接通后,如无医生画面请轻触屏幕任意位置.</view>
			</view>
			<!-- 时间 -->
			<view class="rtc-time" v-if="rtcTime > 0 && isFull">{{rtcTimeFromat(rtcTime)}}</view>
			<!-- 工具栏 -->
			<view class="bot-tool" v-if="isFull">
				<view class="row-item" v-for="(item,index) in tools" :key="index">
					<view class="item-box" v-for="(subItem,subIndex) in item.funs" @click="clickFuns(subItem)">
						<view class="item-img">
							<image :src="subItem.img" mode="aspectFit"></image>
						</view>
						<view class="item-text" v-if="subItem.isSel">{{subItem.title_sel}}</view>
						<view class="item-text" v-else>{{subItem.title}}</view>
					</view>
				</view>
			</view>
			<!-- 加载中 -->
			<view class="loading" v-if="rtcLoading && isFull">
				<view class="loading-img">
					<image src="../static/images/rtc_loading.png" mode=""></image>
				</view>
				<view class="loading-text">正在接通中...</view>
			</view>
		</view>

	</view>
</template>

<script>
	import {
		HTTP_REQUEST_URL
	} from '@/config/app';
	import {
		mapGetters
	} from "vuex";

	// #ifdef H5
	// import AgoraRTC from '../js/AgoraRTC_N-4.14.0.js'
	var agoraScript = document.createElement('script');
	agoraScript.src = HTTP_REQUEST_URL + '/AgoraRTC_N.js';
	document.body.appendChild(agoraScript);
	// #endif

	import Cache from '@/utils/cache.js'
	import {
		rtcChatStart,
		rtcChatAccept,
		rtcChatEnd,
		chatEndIllegal
	} from '@/api/inquiry.js';
	export default {
		name: 'consultRtcNvue',
		props: {
			rtcShow: {
				type: Boolean,
				default: false,
			},
			conversation_id: {
				type: Number | String,
				default: 0
			},
			isDoctor: {
				type: Boolean,
				default: false,
			}
		},
		computed: {
			...mapGetters(['uid']),
		},
		data() {
			return {
				rtcLoading: false,
				rtcTime: 0,
				audioTimer: null,
				timerDestroy: false,
				rtcStyle: 'width:100%;height:100%',
				tools: [{
						id: 100,
						funs: [{
							id: 200,
							img: '../static/images/rtc_rotate.png',
							title: '翻转摄像头',
							title_sel: '翻转摄像头',
						}]
					},
					{
						id: 101,
						funs: [{
								id: 201,
								isSel: false,
								img: '../static/images/rtc_mic.png',
								title: '麦克风已开',
								title_sel: '麦克风已关',
							},
							{
								id: 202,
								isSel: false,
								img: '../static/images/rtc_hang.png',
								title: '挂断',
								title_sel: '挂断',
							},
							{
								id: 203,
								isSel: false,
								img: '../static/images/rtc_voice.png',
								title: '扬声器已开',
								title_sel: '扬声器已关',
							}
						]
					}
				],
				isFull: true,
				rtcClient: null,
				rtcCameras: [],
				rtcMics: [],
				rtcPlayers: [],
				roomInfo: {
					token: '',
					doctor_uid: '',
					patient_uid: '',
					appId: '',
					channelName: '',
				},
				anchorInfo: {
					uid: null,
					audioTrack: null,
					videoTrack: null
				},
				audienceInfo: [],
				isRtcing: false,
				allRtcUsers: [],
				rtcTips: false,
				canPostMsg: false,
				localTracks: {
					videoTrack: null,
					audioTrack: null
				},
			}
		},
		watch: {

		},
		beforeDestroy() {
			console.log("rk===>[生命周期beforeDestroy]");
		},
		destroyed() {
			console.log("rk===>[生命周期destroyed]");
		},
		mounted() {

		},
		methods: {
			clickCtrTips() {
				this.rtcTips = false;
			},
			createTimer() {
				this.destroyTimer();
				this.timerDestroy = false;
				this.rtcTime = 0;
				let that = this;
				this.audioTimer = setInterval(function() {
					if (that.timerDestroy) {
						that.destroyTimer();
						return;
					}
					that.rtcTime += 1;
				}, 1000);
			},
			destroyTimer() {
				console.log("rk===>[计时销毁]" + JSON.stringify());
				this.timerDestroy = true;
				if (this.audioTimer) {
					clearInterval(this.audioTimer);
					this.audioTimer = null;
				}
				this.rtcTime = 0;
			},
			rtcTimeFromat(time) {
				let h = 0,
					m = 0,
					s = 0;
				h = parseInt(time / 3600);
				m = parseInt((time - h * 3600) / 60);
				s = time - h * 3600 - m * 60;
				console.log("rk===>[hx]" + h + '\nrk===>[mx]' + m + '\nrk===>[sx]' + s);
				let timeStr = '';
				if (h > 0) {
					timeStr = this.numFormat(h) + ':';
				}
				if (m > 0) {
					timeStr = timeStr + this.numFormat(m) + ':';
				}
				if (time < 60) {
					timeStr = '00:'
				}
				timeStr = timeStr + this.numFormat(s);
				return timeStr;
			},
			numFormat(n) {
				if (n >= 10) {
					return n
				} else {
					return '0' + n;
				}
			},
			/**
			 * 放到缩小
			 */
			clickChangeFull(flag) {
				this.rtcTips = false;
				if (this.isFull == flag) {
					return
				}
				this.isFull = flag;
				if (flag) {
					this.rtcStyle = 'width:100%;height:100%';
				} else {
					this.rtcStyle = 'width:30%;height:25%';
				}
			},
			/**
			 * 底部功能键
			 */
			clickFuns(subItem) {

				//
				let rtcUser = this.anchorInfo;
				if (this.uid != this.anchorInfo.uid) {
					this.audienceInfo.forEach(value => {
						if (this.uid == value.uid) {
							rtcUser = value;
						}
					})
				}

				console.log("rk===>[uid]" + JSON.stringify(this.uid));
				console.log("rk===>[主播]" + JSON.stringify(this.anchorInfo));
				console.log("rk===>[用户]" + JSON.stringify(this.audienceInfo));

				//subItem.id  200-翻转摄像头; 201-麦克风; 202-挂断; 203-扬声器
				subItem.isSel = !subItem.isSel;

				if (subItem.id == 200) {
					// 摄像头
					console.log("rk===>[摄像头]");
					if (this.rtcCameras.length <= 1) {
						this.$util.Tips({
							title: '操作失败'
						});
						subItem.isSel = !subItem.isSel;
					} else {
						let changeId = this.rtcCameras[0];
						if (subItem.isSel) {
							changeId = this.rtcCameras[1];
						}
						rtcUser.videoTrack.setDevice(changeId).then(() => {
							this.$util.Tips({
								title: '操作成功'
							});
						}).catch(e => {
							this.$util.Tips({
								title: '操作失败'
							});
							// 操作失败恢复状态
							subItem.isSel = !subItem.isSel;
						});
					}

				} else if (subItem.id == 201) {
					// 麦克风
					console.log("rk===>[麦克风]" + subItem.isSel);
					if (rtcUser.audioTrack) {
						rtcUser.audioTrack.setMuted(subItem.isSel).then(() => {
							this.$util.Tips({
								title: '操作成功'
							});
						}).catch(e => {
							console.log("rk===>[切换麦克风]" + e);
							this.$util.Tips({
								title: '操作失败'
							});
							// 操作失败恢复状态
							subItem.isSel = !subItem.isSel;



						});;
					} else {
						this.$util.Tips({
							title: '操作失败'
						});
						// 操作失败恢复状态
						subItem.isSel = !subItem.isSel;
					}

				} else if (subItem.id == 202) {
					// 挂断
					// console.log("rk===>[挂断]" + subItem.isSel);
					this.getChatEnd();

				} else if (subItem.id == 203) {
					// 扬声器
					// console.log("rk===>[扬声器]" + subItem.isSel);
					let that = this;
					this.allRtcUsers.forEach(allRtc => {
						if (allRtc.uid != that.uid) {
							if (subItem.isSel) {
								allRtc.audioTrack.stop();
							} else {
								allRtc.audioTrack.play();
							}
						}
					});
					this.$util.Tips({
						title: '操作成功'
					});
				}

			},
			/**
			 * 结束通话
			 */
			getChatEnd() {
				this.destroyTimer();
				if (!this.isRtcing) {
					return
				}
				Cache.set('RTC_FLAG', 'rtc_end');

				let postDic = {
					conversation_id: this.conversation_id,
				}
				rtcChatEnd(postDic).then(res => {
					let timeStr = res.data.diff;
					this.$emit('rtcHangup', timeStr);
					// 停止推流、离开通道
					this.rtcCancelPush();
					this.$util.Tips({
						title: '通话结束'
					});
				}).catch(res => {
					this.$util.Tips({
						title: res
					});
					this.$emit('rtcHangup');
					// 停止推流、离开通道
					this.rtcCancelPush();
				});
			},
			/**
			 * 结束通话【非正常结束,重置状态】
			 */
			chatEndIllegal() {
				let postDic = {
					conversation_id: this.conversation_id,
				}
				chatEndIllegal(postDic).then(res => {

				}).catch(res => {

				});
			},
			/**
			 * 获取创建Rtc信息
			 */
			getCreateRtcInfo() {

				let platform = uni.getSystemInfoSync().platform;
				console.log("rk===>[platform]" + platform);
				if (platform == 'ios') {
					this.rtcTips = true;
				}

				// 区分医生和患者
				let requesApi = rtcChatAccept;
				if (this.isDoctor) {
					requesApi = rtcChatStart;
				}
				let postDic = {
					conversation_id: this.conversation_id,
				}
				requesApi(postDic).then(res => {
					uni.hideLoading();
					this.roomInfo = res.data;
					console.log("rk===>[房间信息:requesApi]" + JSON.stringify(res));

					this.$emit('rtcShowUI');
					this.rtcInit();
					this.rtcJoinChannel();

				}).catch(res => {
					uni.hideLoading();
					this.$util.Tips({
						title: res
					});
					this.$emit('rtcBusy');
				});
			},
			/**
			 * 获取设备信息
			 */
			rtcGetDevices() {
				// #ifdef H5
				let that = this;
				if (this.rtcCameras.length <= 0) {
					AgoraRTC.getCameras().then(devices => {
						console.log("getCameras device id", devices[0].deviceId);
						devices.forEach(item => {
							that.rtcCameras.push(item.deviceId);
						});
					}).catch(e => {
						console.log("get devices error!", e);
						that.promissionAlert(false);
					});
				}
				if (this.rtcMics.length <= 0) {
					AgoraRTC.getMicrophones().then(devices => {
						console.log("getMicrophones device id", devices[0].deviceId);
						devices.forEach(item => {
							that.rtcMics.push(item.deviceId);
						});
					}).catch(e => {
						console.log("get devices error!", e);
						that.promissionAlert(true);
					});
				}
				/*
				if(this.rtcPlayers.length<=0){
					AgoraRTC.getPlaybackDevices().then(devices => {
						console.log("getPlaybackDevices device id", devices[0].deviceId);
						devices.forEach(item => {
							that.rtcPlayers.push(item.deviceId);
						});
					
					}).catch(e => {
						console.log("get devices error!", e);
					});
				}
				*/

				// #endif
			},
			promissionAlert(isAudio) {
				let alertStr = '麦克风权限受限,建议您检查设备麦克风权限,重启后尝试.';
				if (!isAudio) {
					alertStr = '相机权限受限,建议您检查设备相机权限,重启后尝试.';
				}
				let that = this;
				uni.showModal({
					title: alertStr,
					showCancel: false,
					success(res) {
						if (res.confirm) {
							that.getChatEnd();
						}
					}
				})
			},
			/**
			 * 初始化
			 */
			rtcInit() {

				Cache.set('RTC_FLAG', 'rtc_ing');
				console.log("rk===>[initget]" + Cache.get('RTC_FLAG'));
				let that = this;
				setTimeout(() => {
					that.rtcTips = false;
				}, 10000);
				this.rtcTime = 0;
				// #ifdef H5
				this.rtcLoading = true;
				this.isRtcing = true;
				this.rtcClient = AgoraRTC.createClient({
					mode: "rtc",
					codec: "vp8"
				});
				this.rtcEventOn();


				AgoraRTC.onAutoplayFailed = () => {
					console.log("rk===>[自动播放失败]");
				};
				AgoraRTC.onMicrophoneChanged = async changedDevice => {
					console.log("rk===>[麦克风改变了]");
				};
				AgoraRTC.onCameraChanged = async changedDevice => {
					console.log("rk===>[摄像头改变了]");
				};


				// #endif
			},
			/**
			 * 事件监听
			 */
			rtcEventOn() {
				// #ifdef H5
				//注册事件
				//该回调通知远端用户发布了新的音频轨道或者视频轨道。
				//你可以在该回调中订阅并播放远端用户的音视频轨道
				//如果用户加入频道时频道内已经有其他用户的音视频轨道，也会收到该回调报告已经存在的远端轨道。
				let that = this;
				console.log("rk===>[注册通知：]" + this.rtcClient);

				this.rtcClient.on("user-published", async (rtcUser, mediaType) => {
					console.log("rk===>[收到推流通知]");
					// 订阅

					await that.rtcClient.subscribe(rtcUser, mediaType);
					// 布局处理
					that.isRtcing = true;
					that.rtcLoading = false;
					if (!that.audioTimer) {
						that.createTimer();
					}
					console.log("rk===>[订阅UI处理：]" + rtcUser.uid + '[类型]' + mediaType);
					that.rtcLayoutUI(rtcUser, mediaType, 'subscribe')

				});
				//用户取消推流
				this.rtcClient.on("user-unpublished", user => {
					console.log("rk===>Agora:", "取消推流")
					/*
					let remotePlayerContainer = document.getElementById(user.uid);
					remotePlayerContainer.remove();
					*/
					let rtcUser = that.anchorInfo;
					if (user.uid != that.anchorInfo.uid) {
						that.audienceInfo.forEach(value => {
							if (user.uid == value.uid) {
								rtcUser = value;
							}
						})
					}
					// rtcUser.audioTrack.stop();
				});
				// 用户加入
				this.rtcClient.on("user-joined", user => {
					console.log("rk===>Agora:用户加入" + user.uid);

				});
				// 用户离开
				this.rtcClient.on("user-left", user => {
					console.log("rk===>Agora:用户离开" + user.uid);
					this.rtcLoading = false;
					that.getChatEnd();
				});
				// 监听状态
				this.rtcClient.on("connection-state-change", (curState, revState, reason) => {
					console.log("rk===>[connection-state-change]" + curState);
					console.log("rk===>[connection-state-change]" + revState);
					console.log("rk===>[connection-state-change]" + reason);
					if (curState == 'DISCONNECTED' && reason == 'LEAVE') {
						that.chatEndIllegal();
					}
				});
				// #endif
			},
			/**
			 * 加入通道
			 */
			async rtcJoinChannel() {
				let that = this;
				let appId = this.roomInfo.appId;
				let channelName = this.roomInfo.channelName;
				let rtcToken = this.roomInfo.token;

				//加入通道
				this.rtcClient.join(appId, String(channelName), rtcToken, parseInt(this.uid))
					.then(res => {
						console.log("rk===>Agora:", "加入通道成功")
						that.rtcStartPush();
					})
					.catch(error => {
						console.log("rk===>Agora:", "加入通道失败：", error)
						console.log("rk===>Agora:", "加入通道失败：", JSON.stringify(error.message))
						let errMsg = error.message;
						let errFlag = errMsg.includes('WS_ABORT');
						if (errFlag) {
							errMsg = '网络错误,请重试'
						}
						this.$util.Tips({
							title: errMsg
						});
						that.$emit('rtcHangup');
						that.chatEndIllegal();

						// rk_tips
						// uni.showModal({
						// 	title:'提示:',
						// 	content:error.message+'\n[uid:]'+this.uid+'\n[token]'+rtcToken+'\n[channel]'+channelName,
						// 	success() {
						// 	}
						// });
					})

				// let joinRes = await this.rtcClient.join(appId, String(channelName), rtcToken, parseInt(this.uid));
				// this.rtcStartPush(); 
			},

			async rtcStartPush() {
				// 获取设备信息
				this.rtcGetDevices();
				if (!this.localTracks.audioTrack || !this.localTracks.videoTrack) {
					// this.localTracks.audioTrack = await AgoraRTC.createMicrophoneAudioTrack({
					// 	encoderConfig: "music_standard"
					// });
					[this.localTracks.audioTrack, this.localTracks.videoTrack] = await AgoraRTC
					.createMicrophoneAndCameraTracks({
						audioConfig: {
							encoderConfig: "music_standard"
						},
						videoConfig: {
							encoderConfig: "720p_2"
						},
					});
				}
				console.log("rk===>[开始检测]");
				console.log("rk===>[开始检测+]" + this.localTracks.audioTrack);
				let that = this;

				let localRtcUser = {};
				localRtcUser.audioTrack = this.localTracks.audioTrack;
				localRtcUser.videoTrack = this.localTracks.videoTrack
				localRtcUser.uid = this.uid;
				this.rtcLayoutUI(localRtcUser, 'video', 'local-video');
				this.rtcLayoutUI(localRtcUser, 'audio', 'local-video');

				await this.rtcClient.publish(Object.values(this.localTracks));

				// // 获取设备信息
				// this.rtcGetDevices();
			},
			/**
			 * 根据userid获取view
			 */
			getViewWithUserid(userId) {
				// console.log("rk===>[rtcViewUserid]" + userId);
				// console.log("rk===>[rtcViewUid]" + this.uid);
				// console.log("rk===>[rtcView1]" + this.$refs.videoSmall);
				// console.log("rk===>[rtcView2]" + this.$refs.videoBig);
				if (userId == this.uid) {
					return this.$refs.videoSmall;
				}
				return this.$refs.videoBig;
			},
			/**
			 * 推流成功、或者订阅到推流信息开始布局处理
			 */
			rtcLayoutUI(rtcUser, mediaType, from) {

				let index = this.allRtcUsers.findIndex(value => value.uid == rtcUser.uid)
				let remoteJoin = {}
				if (index < 0) {
					this.allRtcUsers.push(rtcUser)
				}

				console.log("rk===>[UIfrom]" + from);
				console.log("rk===>[推流后-处理UI]" + JSON.stringify(rtcUser));
				if (rtcUser.uid == this.roomInfo.doctor_uid) {
					// 主播
					console.log("rk===>[收到主播====mediaType]", mediaType);
					this.anchorInfo.uid = rtcUser.uid;
					if (mediaType === "video") {
						let videoTrack = rtcUser.videoTrack
						this.anchorInfo.videoTrack = videoTrack
						let playView = this.getViewWithUserid(rtcUser.uid);

						// const remotePlayerContainer = document.createElement("div");
						// remotePlayerContainer.id = rtcUser.uid;
						// remotePlayerContainer.style.width = '100px'
						// remotePlayerContainer.style.height = '300px'
						// remotePlayerContainer.style.border = '#000 1px solid'
						// remotePlayerContainer.style.backgroundColor = '#ccc'
						// remotePlayerContainer.style.boxSizing = 'border-box'
						// playView.append(remotePlayerContainer);

						videoTrack.play(playView)
					} else if (mediaType === "audio") {
						let audioTrack = rtcUser.audioTrack
						this.anchorInfo.audioTrack = audioTrack
						audioTrack.play()
					}
				} else {
					// 普通用户
					console.log("rk===>[收到其他====]");
					let index = this.audienceInfo.findIndex(value => value.uid == rtcUser.uid)
					let joinUser = {}
					if (index < 0) {
						joinUser.uid = rtcUser.uid;
						this.audienceInfo.push(joinUser)
					} else {
						joinUser = this.audienceInfo[index]
					}
					if (mediaType === "video") {
						joinUser.videoTrack = rtcUser.videoTrack;
						/*
						let joinContainer = document.createElement("div");
						joinContainer.id = rtcUser.uid;
						joinContainer.style.width = '140px'
						joinContainer.style.height = '200px'
						joinContainer.style.border = '#000 1px solid'
						joinContainer.style.backgroundColor = '#ccc'
						joinContainer.style.boxSizing = 'border-box'
						this.$refs.videoSmall.append(joinContainer);
						joinUser.videoTrack.play(joinContainer)
						*/
						let playView = this.getViewWithUserid(rtcUser.uid);
						console.log("rk===>[playview]" + playView);
						joinUser.videoTrack.play(playView)
					} else if (mediaType === "audio") {
						joinUser.audioTrack = rtcUser.audioTrack
						joinUser.audioTrack.play()
					}
				}
			},
			/**
			 * 取消推流、离开房间
			 */
			async rtcCancelPush() {
				// #ifdef H5

				let that = this;
				if (this.localTracks.audioTrack || this.localTracks.videoTrack) {
					await this.rtcClient.unpublish()
				}
				if (this.localTracks.audioTrack) {
					this.localTracks.audioTrack.stop();
					this.localTracks.audioTrack.close();
					this.localTracks.audioTrack = null;
				}
				if (this.localTracks.videoTrack) {
					this.localTracks.videoTrack.stop();
					this.localTracks.videoTrack.close();
					this.localTracks.videoTrack = null;
				}
				that.isRtcing = false;
				that.rtcClient.leave().then(res => {
					console.log("Agora:", "离开通道：", res)
				})
				// #endif
			}
		}
	}
</script>

<style lang="scss">
	.com-counsult-rtc {
		position: absolute;
		right: 0;
		top: 0px;
	}

	.rtc-bg {
		width: 100%;
		height: 100%;
		background-color: rgba(0, 0, 0, 0.5);
		position: relative;

		.rtc-zoom {
			position: absolute;
			display: flex;
			justify-content: center;
			align-items: center;
			left: 10rpx;
			top: 10rpx;
			width: 80rpx;
			height: 80rpx;
			color: #fff;
			z-index: 100;

			.yyfont {
				font-size: 22px;
			}
		}

		.rtc-tips-box {
			position: absolute;
			z-index: 101;
			width: 100%;
			display: flex;
			justify-content: center;

			.rtc-tips {
				background-color: #F5E9D1;
				color: #EEBB42;
				font-size: 20rpx;
				padding: 10rpx 20rpx;
				border-radius: 10rpx;
			}

		}

		.rtc-time {
			position: absolute;
			color: #fff;
			top: 30rpx;
			left: 30%;
			font-weight: bold;
			z-index: 100;
		}

		.video-big {
			position: absolute;
			left: 0;
			top: 0;
			width: 100%;
			height: 100%;
			background-color: rgba(0, 0, 0, 0.9);
		}

		.video-small {
			position: absolute;
			top: 0;
			right: 0;
			background-color: rgba(0, 0, 0, 0.9);
			border: 1rpx solid #323232;
			border-radius: 5px;
			overflow: hidden;
			width: 40%;
			height: 30%;
		}

		.bot-tool {
			position: absolute;
			width: 100%;
			bottom: 40rpx;

			.row-item {
				display: flex;
				justify-content: space-evenly;
				padding-bottom: 50rpx;

				.item-box {
					display: flex;
					flex-direction: column;
					justify-content: center;
					align-items: center;

					.item-img {
						image {
							width: 80rpx;
							height: 80rpx;
						}
					}

					.item-text {
						color: #fff;
					}
				}
			}
		}

		.loading {
			position: absolute;
			top: 36%;
			display: flex;
			flex-direction: column;
			justify-content: center;
			align-items: center;

			.loading-img {
				display: flex;
				justify-content: center;
				align-items: center;
				padding: 100rpx 100rpx 80rpx;
				background-color: rgba(0, 0, 0, 0.8);
				border-radius: 50rpx;

				image {
					width: 200rpx;
					height: 200rpx;

					animation: loadingRotate 1.5s linear infinite;
					-moz-animation: loadingRotate 1.5s linear infinite;
					-webkit-animation: loadingRotate 1.5s linear infinite;
					-o-animation: loadingRotate 1.5s linear infinite;
				}
			}

			.loading-text {
				padding-bottom: 20rpx;
				color: #fff;
			}

			@keyframes loadingRotate {
				0% {
					transform: rotate(0deg);
				}

				100% {
					transform: rotate(360deg);
				}
			}
		}
	}
</style>